package drug

import (
	"Project/global"
	"Project/model/common"
	"Project/model/common/request"
	"Project/model/drugs"
	req "Project/model/drugs/request"
	"Project/model/drugs/response"
	"Project/model/user"
	"Project/utils"
	"gorm.io/gorm"
	"time"
)

type DrugRecordService struct{}

// AddDrugRecord 增加购药记录（废除）
func (s *DrugRecordService) AddDrugRecord(record *drugs.DrugsRecord) error {
	err := global.GVA_DB.Create(record).Error
	return err
}

// DeleteDrugRecord 删除购药记录
func (s *DrugRecordService) DeleteDrugRecord(recordId int64) error {
	err := global.GVA_DB.Transaction(func(tx *gorm.DB) error {
		// 删除登记表中记录
		if err := global.GVA_DB.Debug().Where("record_id=?", recordId).Delete(&drugs.DrugsRecord{}).Error; err != nil {
			return err
		}
		// 删除middle表中记录
		if err := global.GVA_DB.Debug().Where("record_id=?", recordId).Delete(&drugs.DrugsMiddle{}).Error; err != nil {
			return err
		}
		return nil
	})
	return err
}

// UpdateDrugRecord 更新购药记录
func (s *DrugRecordService) UpdateDrugRecord(recordId int64, drugRecord req.DrugRecordRequest) error {
	// 填充要更新的字段
	var record = drugs.DrugsRecord{
		Name:       drugRecord.Name,
		Phone:      drugRecord.Phone,
		Card:       drugRecord.Card,
		LivingArea: drugRecord.LivingArea,
		Address:    drugRecord.Address,
		HighRisk:   drugRecord.HighRisk,
		ReasonUse:  drugRecord.ReasonUse,
	}
	druglist := drugRecord.DrugList
	for i := 0; i < len(druglist); i++ {
		druglist[i].RecordID = recordId
	}
	// 开启事务处理
	err := global.GVA_DB.Debug().Transaction(func(tx *gorm.DB) error {
		// 删除中间表中的该记录的所购药品信息
		if err := global.GVA_DB.Debug().Where("record_id=?", recordId).Delete(&drugs.DrugsMiddle{}).Error; err != nil {
			return err
		}
		// 更新购药记录
		if err := global.GVA_DB.Debug().Model(&drugs.DrugsRecord{}).Where("record_id=?", recordId).Updates(record).Error; err != nil {
			return err
		}
		// 新增药品记录
		if err := global.GVA_DB.Debug().Create(&druglist).Error; err != nil {
			return err
		}
		return nil
	})
	return err
}

// GetAllDrugRecord 获取购药记录列表 （废除）
func (s *DrugRecordService) GetAllDrugRecord() ([]drugs.DrugsRecord, error) {
	list := []drugs.DrugsRecord{}
	err := global.GVA_DB.Model(&drugs.DrugsRecord{}).Debug().Find(&list).Error
	return list, err
}

// GetAllDrugRecordByShopId 获取药店所有购药记录
func (s *DrugRecordService) GetAllDrugRecordByShopId(saleID int64, req *req.InquireDrugRecordRequest) ([]response.DrugsRecordWithYaoPin, int64, error) {
	// 查询对应药店id
	var shopId int64
	if err := global.GVA_DB.Debug().Select("shop_id").Model(&user.UserSale{}).First(&shopId, "sale_id=?", saleID).Error; err != nil {
		return nil, 0, err
	}
	// 查询购药记录
	req.DrugsShopId = shopId
	recordList, total, err := getRecordByShopId(req)
	if err != nil {
		return nil, 0, err
	}
	// 将药品记录与购药记录绑定
	drugsRecordList, err := getRecordWithDrugs(recordList)
	if err != nil {
		return nil, 0, err
	}
	// 返回
	return drugsRecordList, total, nil
}

// GetRecordList 获取所有的购药记录
func (s *DrugRecordService) GetRecordList(req *request.ConditionAndPageInfo) ([]response.DrugsRecordWithYaoPin, int64, error) {
	// 查询购药记录
	recordList, total, err := getRecord(req)
	if err != nil {
		return nil, 0, err
	}
	// 绑定药品记录到购药记录
	drugRecordListWithDrugs, err := getRecordWithDrugs(recordList)
	if err != nil {
		return nil, 0, err
	}
	return drugRecordListWithDrugs, total, nil
}

//SaveDrugRecord 存储购药信息（购药表，中间表）
func (s *DrugRecordService) SaveDrugRecord(saleId int64, record req.DrugRecordRequest) error {
	// 获取销售人员姓名，以及所在药店的id
	var userSale user.UserSale
	if err := global.GVA_DB.Debug().Select([]string{"user_name", "shop_id"}).First(&userSale, "sale_id=?", saleId).Error; err != nil {
		return err
	}
	// 获取药店所在县区的id
	var areaId int64
	if err := global.GVA_DB.Debug().Model(&drugs.DrugsShop{}).Select([]string{"area_id"}).First(&areaId, "drugs_shop_id=?", userSale.ShopID).Error; err != nil {
		return err
	}
	// 生成购药记录
	drugRecord := drugs.DrugsRecord{
		RecordID:    utils.GenID(),
		DrugsShopID: userSale.ShopID,
		AreaID:      areaId,
		SaleName:    userSale.UserName,
		Name:        record.Name,
		Phone:       record.Phone,
		Card:        record.Card,
		LivingArea:  record.LivingArea,
		Address:     record.Address,
		HighRisk:    record.HighRisk,
		ReasonUse:   record.ReasonUse,
	}
	// 生成所购药品记录（middle表）
	drugs := record.DrugList
	for i := 0; i < len(drugs); i++ {
		drugs[i].RecordID = drugRecord.RecordID // 设置 记录对应的购药记录id
	}
	// 开启事务处理
	err := global.GVA_DB.Transaction(func(tx *gorm.DB) error {
		// 存储购药记录
		if err := global.GVA_DB.Debug().Create(&drugRecord).Error; err != nil {
			return err
		}
		// 存储所购药品
		if err := global.GVA_DB.Debug().Create(&drugs).Error; err != nil {
			return err
		}
		return nil
	})
	return err
}

// 查询购药记录带有药店id
func getRecordByShopId(req *req.InquireDrugRecordRequest) ([]drugs.DrugsRecord, int64, error) {

	// 购药记录
	var recordList []drugs.DrugsRecord
	condInfo := req.ConditionAndPageInfo.Condition
	pageInfo := req.ConditionAndPageInfo.PageInfo
	var total int64
	// 首先找到药店id相关的所有购药记录，再根据模糊字段进行匹配，最后，根据创建时间筛选，并排序
	var err error
	if condInfo.FuzzyField == "" {
		err = global.GVA_DB.Debug().Model(&drugs.DrugsRecord{}).Where("drugs_shop_id=? and created_at >= ? and created_at <=?",
			req.DrugsShopId, condInfo.StartTime, condInfo.EndTime).Order("created_at desc").Count(&total).
			Offset((pageInfo.PageNum - 1) * pageInfo.PageSize).Limit(pageInfo.PageSize).Scan(&recordList).Error
	} else {
		err = global.GVA_DB.Debug().Model(&drugs.DrugsRecord{}).
			Where("drugs_shop_id=? and concat(sale_name,name,card,phone, address) like ? and created_at >= ? and created_at <=?",
				req.DrugsShopId, "%"+condInfo.FuzzyField+"%", condInfo.StartTime, condInfo.EndTime).Count(&total).Order("created_at desc").
			Offset((pageInfo.PageNum - 1) * pageInfo.PageSize).Limit(pageInfo.PageSize).Scan(&recordList).Error
	}
	if err != nil {
		return nil, 0, err
	}
	return recordList, total, nil
}

// 将药品记录的药品 与对应记录进行绑定
func getRecordWithDrugs(recordList []drugs.DrugsRecord) ([]response.DrugsRecordWithYaoPin, error) {
	// 获取购药记录 ID 列表，用于中间表 in 查询，
	recordIdList := make([]int64, 0, len(recordList))
	for _, record := range recordList {
		recordIdList = append(recordIdList, record.RecordID)
	}

	// 中间表记录
	var middleList []drugs.DrugsMiddle
	err := global.GVA_DB.Debug().Model(&drugs.DrugsMiddle{}).Where("record_id in ?", recordIdList).Find(&middleList).Error
	if err != nil {
		return nil, err
	}

	// map用于去重，相同登记记录id的药品放在同一个key下
	recordDrugsMap := make(map[int64][]response.Drug, len(recordIdList))
	for i := 0; i < len(middleList); i++ {
		drugs := recordDrugsMap[middleList[i].RecordID]
		drugs = append(drugs, response.Drug{
			DrugName: middleList[i].DrugName,
			DrugNum:  middleList[i].DrugNum,
		})
		recordDrugsMap[middleList[i].RecordID] = drugs
	}

	// 将登记记录和药品记录合并
	var drugsRecordList = make([]response.DrugsRecordWithYaoPin, len(recordList))
	for i := 0; i < len(recordList); i++ {
		drugsRecordList[i].DrugsRecord = recordList[i]
		drugsRecordList[i].DrugList = append(drugsRecordList[i].DrugList, recordDrugsMap[recordList[i].RecordID]...)
	}
	return drugsRecordList, nil
}

// 查询购药记录
func getRecord(req *request.ConditionAndPageInfo) ([]drugs.DrugsRecord, int64, error) {
	var recordList []drugs.DrugsRecord // 购药记录
	condInfo := req.Condition
	pageInfo := req.PageInfo
	var total int64
	// 首先找到药店id相关的所有购药记录，再根据模糊字段进行匹配，最后，根据创建时间筛选，并排序
	var err error
	if condInfo.FuzzyField == "" {
		err = global.GVA_DB.Debug().Model(&drugs.DrugsRecord{}).Where("created_at >= ? and created_at <=?",
			condInfo.StartTime, condInfo.EndTime).Order("created_at desc").Count(&total).
			Offset((pageInfo.PageNum - 1) * pageInfo.PageSize).Limit(pageInfo.PageSize).Scan(&recordList).Error
	} else {
		err = global.GVA_DB.Debug().Model(&drugs.DrugsRecord{}).
			Where("concat(sale_name,name,card,phone, address) like ? and created_at >= ? and created_at <=?",
				"%"+condInfo.FuzzyField+"%", condInfo.StartTime, condInfo.EndTime).Count(&total).Order("created_at desc").
			Offset((pageInfo.PageNum - 1) * pageInfo.PageSize).Limit(pageInfo.PageSize).Scan(&recordList).Error
	}
	if err != nil {
		return nil, 0, err
	}
	return recordList, total, nil
}

// 统计记录
func (s *DrugRecordService) GetResByTime(start, end time.Time) (res []common.StatisticRes, err error) {
	err = global.GVA_DB.Debug().Model(&drugs.DrugsShop{}).Select([]string{"name", "count_num"}).Joins("left join( select drugs_shop_id as shop_id, count(drugs_shop_id) as count_num "+
		"FROM drugs_record where created_at >= ? and created_at <=? GROUP BY drugs_shop_id) as tmp on drugs_shop_id = shop_id", start, end).Find(&res).Error
	return
}

// 统计至今没有购药记录的药店
func (s *DrugRecordService) GetResSince() (res []string, err error) {
	var shop_id []int64
	err = global.GVA_DB.Model(&drugs.DrugsRecord{}).Distinct().Pluck("drugs_shop_id", &shop_id).Error
	if err != nil {
		return nil, err
	}
	err = global.GVA_DB.Debug().Model(&drugs.DrugsShop{}).Select("name").Where("drugs_shop_id not in ?", shop_id).Find(&res).Error
	return
}
